package ysq.xyg.controller;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import ysq.weixin.client.WxApiClient;
import ysq.weixin.client.WxMemoryCacheClient;
import ysq.weixin.model.info.OAuthAccessToken;
import ysq.weixin.model.info.OAuthScope;
import ysq.weixin.model.info.User;
import ysq.weixin.util.WxUrlUtil;
import ysq.xyg.model.Member;
import ysq.xyg.model.info.WxAccountInfo;
import ysq.xyg.service.MemberService;
import ysq.xyg.util.BaseConstant;
import ysq.xyg.util.BaseUtil;
import ysq.xyg.util.ProProperties;

import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Date;

/**
 * Created by Administrator on 2017/6/23 0023.
 */
@Controller
@RequestMapping("/weiXin")
public class WeXinController extends BaseController {
    private static final Logger log= LoggerFactory.getLogger(WeXinController.class);

    @Autowired
    private MemberService memberService;

    /**
     * oauth2.0跳转入库
     * state:1.首页,2,添加页面
     * */
    @RequestMapping("/oauth/{state}")
    public ModelAndView oauth(HttpServletResponse response, HttpServletRequest request, @PathVariable String state) throws IOException {
        String oauthType = request.getParameter("oauthType");
        String scope= OAuthScope.Base.toString();
        if(OAuthScope.Userinfo.toString().equals(oauthType)){
            scope=OAuthScope.Userinfo.toString();
        }
        WxAccountInfo wxAccountInfo = WxMemoryCacheClient.getSingleWxAccountInfo();//获取缓存中的唯一账号
        String url = WxUrlUtil.getOAuthCodeUrl(wxAccountInfo.getAppid(), wxAccountInfo.getBaseURL()+ ProProperties.getInstance().getWxOauthAcceptOpenidURL(),scope, state);
        return new ModelAndView("redirect:" + url);
    }

    /**
     * 获取openid 并跳转
     * */
    @RequestMapping("/acceptOpenid")
    public ModelAndView acceptOpenid(HttpServletResponse response, HttpServletRequest request) throws IOException {
        String code = request.getParameter("code");
        // 获取到的state是模式页面组合，模式由一个字符，1表示base,2表示userinfo,其他为页面标识符
        String scopeState = request.getParameter("state");
        String scope= scopeState.substring(0,1);
        String state = scopeState.substring(1,scopeState.length());
        String introductId = request.getParameter("introductId");
        if(StringUtils.isEmpty(introductId)){
            introductId=BaseConstant.INTRODUCT_USER_ID;
        }
        log.info("scopeState is "+scopeState+"code is "+code+";state is "+state+";scope is "+scope);
        ModelAndView modelAndView=null;
        try {
            // 获取缓存中的唯一账号
            WxAccountInfo wxAccountInfo = WxMemoryCacheClient.getSingleWxAccountInfo();
            OAuthAccessToken oAuthAccessToken = WxApiClient.getOAuthOpenId(wxAccountInfo, code);
            log.info("openid is "+oAuthAccessToken.getOpenid());
            if (StringUtils.isEmpty(oAuthAccessToken.getOpenid())) {
                //跳转到oauth2.0的url
                String url = WxUrlUtil.getOAuthCodeUrl(wxAccountInfo.getAppid(), wxAccountInfo.getBaseURL()+ ProProperties.getInstance().getWxOauthAcceptOpenidURL(),OAuthScope.Base.toString(), state);
                modelAndView =  new ModelAndView("redirect:" + url);
            }else{
                //判断当前用户是否已经保存到数据库
                Member member = createUser(oAuthAccessToken, scope,introductId);
                if (member != null) {
                    modelAndView = acceptView(member,state,oAuthAccessToken);
                } else {
                    //跳转到oauth2.0的url
                    String url = WxUrlUtil.getOAuthCodeUrl(wxAccountInfo.getAppid(), wxAccountInfo.getBaseURL()+ ProProperties.getInstance().getWxOauthAcceptOpenidURL()+"?introductId="+introductId,OAuthScope.Userinfo.toString(), state);
                    modelAndView =  new ModelAndView("redirect:" + url);
                }
                return modelAndView;
            }
        } catch (Exception e) {
            //跳转错误页面
            e.printStackTrace();
        }
        return modelAndView;
    }
    protected ModelAndView acceptView(Member member, String state,OAuthAccessToken oAuthAccessToken){
        ModelAndView modelAndView=null;
        if (BaseConstant.WX_STATE_ONE.equals(state)) {
            modelAndView = new ModelAndView("redirect:"+ProProperties.getInstance().getWxOauthRredirectIndexURL(member.getId()));
        }else {
            //默认页面
            modelAndView = new ModelAndView("redirect:"+ProProperties.getInstance().getWxOauthRredirectIndexURL(member.getId()));
        }
        return  modelAndView;
    }

    /**
     * 创建本地用户
     * @return
     */
    protected Member createUser(OAuthAccessToken oAuthAccessToken,String scope,String introductUserId){
        Member member=memberService.selectEntityByOpenid(oAuthAccessToken.getOpenid());
        if(member == null){
            // 用户不存在
            if(BaseConstant.OAUTH_USERINFO.equals(scope)){
                //Oauth为获取用户信息模式
                User user=WxApiClient.getOAuthUserInfo(oAuthAccessToken);
                if(user!=null){
                    //将用户信息插入数据库
                    member=new Member();
                    int id = memberService.selectMaxId();
                    if (id < BaseConstant.MEMBER_MIN_DEFAULT_ID) {
                        id = BaseConstant.MEMBER_MIN_DEFAULT_ID;
                    } else {
                        id = id + 1;
                    }
                    member.setId(String.valueOf(id));
                    member.setOpenid(user.getOpenid());
                    member.setHeadImage(user.getHeadlogo());
                    member.setNickName(BaseUtil.encodeBase64String(user.getNickname()));
                    member.setCreateTime(new Date());
                    member.setIntroductUserId(introductUserId);
                    int ids=memberService.insert(member);
                    if(ids>0){
                        return member;
                    }
                }
            }
            return null;
        }else{
            //用户存在
            return member;
        }
    }


    //从输入流读取post参数
    protected String readStreamParameter(ServletInputStream in){
        StringBuilder buffer = new StringBuilder();
        BufferedReader reader=null;
        try{
            reader = new BufferedReader(new InputStreamReader(in,"UTF-8"));
            String line=null;
            while((line = reader.readLine())!=null){
                buffer.append(line);
            }
        }catch(Exception e){
            e.printStackTrace();
        }finally{
            if(null!=reader){
                try {
                    reader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return buffer.toString();
    }
}
